/* Copyright 2012 Ilkka Kiistala

This file is part of the Crossmodal-Framework. The Crossmodal-Framework is free software: you can redistribute it and/or modify it under the terms of the GNU 
General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

The Crossmodal-Framework is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along 
with the Crossmodal Framework.  If not, see <http://www.gnu.org/licenses/> */

package com.example.jsontotactons;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Vibrator;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class JSONtoTactons extends Activity implements OnClickListener
{
	private static final long DEFAULT_DELAY = 5000;
	private static final String DEFAULT_EXPERIMENTNAME = "Unnamed experiment";
	private String json_text;
	// protected String url_json = "http://kiistala.com/cm/json/jsontotactons";
	protected String url_json = "http://www.cs.helsinki.fi/group/interact/tactonapp/jsontotactons";
	// private long delay = 1000L;

	// Tacton[] tactons = null;
	// ArrayList<Tacton> tactons = new ArrayList();
	Experiment exp = null;
	JSONObject jObject = null;
	private int currentTacton;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		initializeStartButton();
		// initializeTestTactons();
		// initializeExperiment();
		// currentTacton = 0;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.menu, menu);
		return true;
	}

	private void initializeStartButton() {
		View startButton = findViewById(R.id.start_button);
		startButton.setOnClickListener(this);
	}

	private void initializeTestTactons() {
		ArrayList<Tacton> testTactonList = new ArrayList<Tacton>();
		// testTactonList.add(new Tacton("tt0", new long[]{1000L, 20L, 20L}));
		// testTactonList.add(new Tacton("tt0", new long[]{20L, 20L, 20L}));
		// testTactonList.add(new Tacton("tt1", new long[]{1000L, 20L, 500L}));
		// long[] pattern = new long[]{0, 100, 100, 100, 100, 100, 100, 100, 100, 100};

		testTactonList.add(new Tacton("tt0", new long[]{1000L} ));
		testTactonList.add(new Tacton("tt1", new long[]{100, 100, 100, 100, 100, 100, 100, 100, 100} ));
		testTactonList.add(new Tacton("tt2", new long[]{200, 100, 400, 100, 600} ));

		exp = new Experiment("Test Experiment", testTactonList);

	}

	private void initializeExperiment() {

		//		testTactonList.add(new Tacton("tt0", new long[]{1000L} ));
		//		testTactonList.add(new Tacton("tt1", new long[]{100, 100, 100, 100, 100, 100, 100, 100, 100} ));
		//		testTactonList.add(new Tacton("tt2", new long[]{200, 100, 400, 100, 600} ));
		//		tactonList.add(new Tacton("t1", new long[]{200, 100, 400, 100, 600} ));


		// empty list
		ArrayList<Tacton> tactonList = new ArrayList<Tacton>();
		exp = new Experiment(jObject.optString("experimentName", DEFAULT_EXPERIMENTNAME), jObject.optLong("delay", DEFAULT_DELAY), tactonList);
		currentTacton = 0;

	}


	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		switch (item.getItemId())
		{
		case R.id.about:
			// Logger.d("Displaying the about box");
			// displayAboutBox();
			return true;
		case R.id.load_experiments:
			String result = null;

			// Logger.d("Displaying the team configuration");
			// displayConfiguration();

			try {
				result = HTTPGetCall(url_json);
				json_text = result;
			} catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			// import JSON

			// JSONObject jObject;
			// jOb

			try {
				jObject = new JSONObject(result);
				initializeExperiment();

				JSONArray tests = jObject.optJSONArray("stimuli");

				if (tests != null) { 
					int tlen = tests.length();

					for (int i=0;i < tlen;i++) { 
						// ArrayList<JSONAr> list = new ArrayList<long>();
						JSONArray times = (JSONArray)tests.getJSONArray(i);
						// exp.addJSONTacton(times);

						if (times != null)
						{ 
							int len = times.length();
							long[] longs = new long[len];
							for (int j = 0;j < len;j++)
							{ 
								longs[j] = times.optLong(j);
							}
							
							exp.addTacton(new Tacton(longs));
						} 

					} 
				} 

				
//				JSONArray jsonArray = (JSONArray)tests; 
//				if (jsonArray != null) { 
//					int len = jsonArray.length();
//					for (int i=0;i<len;i++){ 
//						list.add(jsonArray.get(i).toString());
//					} 
//				} 

				// Logger.d( list.toString() );

				//	            try {
					//					result = jObject.getString("repeat");
				//				} catch (JSONException e) {
				//					// TODO Auto-generated catch block
				//					e.printStackTrace();
				//				}
				//
				//				
			} catch (JSONException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}

			// t("JSON: " + json_text);

			updateDisplay();

			return true; 

		default:
			t("Unhandled choice");
			// Logger.e("Unknown menu item selected");
			return false;
		}
	}

	// **

	private void updateDisplay() {
		TextView expLabel = (TextView) findViewById(R.id.experiment_label);
		TextView expinfo = (TextView) findViewById(R.id.experiment_info);
		Button start = (Button) findViewById(R.id.start_button);

		if (exp != null)
		{
			start.setEnabled(true);
			expLabel.setText(exp.getName());
			expinfo.setText("delay between tests: " + exp.getDelay() + " ms\nTests: " + exp.getTactonCount());
		}
	}

	private void t(String text) {
		toastThis(text, Toast.LENGTH_LONG);
	}

	public void toastThis(String text, int duration)
	{
		Context context = getApplicationContext();
		Toast t;
		t = Toast.makeText(context, text, duration);
		t.show();
		return;	
	}

	public void toastQuick(String text)
	{
		// int duration = Toast.LENGTH_LONG;
		toastThis(text, Toast.LENGTH_SHORT);
	}

	protected String HTTPGetCall(String WebMethodURL) throws IOException, MalformedURLException 
	{ 
		StringBuilder response = new StringBuilder(); 

		//Prepare the URL and the connection 
		URL u = new URL(WebMethodURL); 
		HttpURLConnection conn = (HttpURLConnection) u.openConnection(); 

		if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) 
		{ 
			//Get the Stream reader ready 
			BufferedReader input = new BufferedReader(new InputStreamReader(conn.getInputStream()),8192); 

			//Loop through the return data and copy it over to the response object to be processed 
			String line = null; 

			while ((line = input.readLine()) != null) 
			{ 
				response.append(line); 
			} 

			input.close(); 
		} 

		return response.toString(); 
	}

	public void onClick(View v)
	{
		switch (v.getId()) {
		case R.id.start_button:

			// toastThis("Start button clicked " + v.getId() );

			// Intent intent = new Intent(this, ExperimentTimer.class);
			// Logger.i("Tactons loaded: " + text);

			// i.putExtra("tacton1", tactons.get(0).getStructure());
			// startTimer(intent);

			TextView testLabel = (TextView) findViewById(R.id.test);
			TextView testInfo = (TextView) findViewById(R.id.test_info);

			//            TextView expLabel = (TextView) findViewById(R.id.experiment_label);
			//            expLabel.setText(exp.getName());
			//
			//            TextView expinfo = (TextView) findViewById(R.id.experiment_info);
			//            expinfo.setText("delay between tests: " + delay + " ms");

			Button start = (Button) findViewById(R.id.start_button);

			// testLabel.setTextColor(TimeFormatHelper.determineColor(remainingIndividualSeconds, warningTime));

			if (currentTacton < exp.getTactonCount())
			{
				// Tacton[] tactons = null;
				//				ArrayList<Tacton> tactons = exp.getTactons();
				//
				//				for (int i = 0; i < tactons.size(); i++)
				//				{
				// Tacton tacton = tactons.get(i);
				Tacton tacton = exp.getTacton(currentTacton); 

				testLabel.setText("Tacton number " + (currentTacton + 1) + "/" + exp.getTactonCount());
				testInfo.setText("[" + tacton.getTimes() + "]");

				// toastQuick("doing delay for " + delay + " ms");
				// pause(exp.getDelay());
				// toastQuick("playing a Tacton: " + tacton);
				playTacton(tacton);
				currentTacton++;

				if (currentTacton >= exp.getTactonCount())
				{
					// t("That was last of Tactons.");
					start.setText("Start over");
					currentTacton = 0;
				}
				else
				{
					start.setText("Next");
				}


				// gets displayed before really Done

				// displayTactonList();

				//				}
			}
			else
			{
				t("Experiment has no Tests.");
			}

			return;
		default:
			t("Unknown click: " + v.getId() );
			return;
		}
	}

	private void pause(long duration)
	{
		try {
			// wait until the Tacton is finished
			Thread.sleep(duration);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	private void VibratePhone(long[] pattern)
	{
		Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
		// -1 is for not repeating
		// first value in pattern is a waiting time

		//pattern = new long[]{0L, 20L, 20L, 20L, 20L, 20L};
		//pattern = new long[]{0L, 200L, 200L, 200L, 200L, 200L, 200L, 200L};
		//pattern = new long[]{0, 100, 100, 100, 100, 100, 100, 100, 100, 100};
		v.vibrate(pattern, -1);
	}

	private void playTacton(Tacton t)
	{
		Logger.d("playing Tacton: " + t);
		long[] delayArray = new long[]{exp.getDelay()};
		long[] longs = t.getStructure();
		long[] pattern = new long[ delayArray.length + longs.length];
		System.arraycopy(delayArray, 0, pattern, 0, delayArray.length);
		System.arraycopy(longs, 0, pattern, delayArray.length, longs.length);
		// Arrays.addAll( new long[]{50}, t.getStructureLongs() );
		// VibratePhone(t.getStructureLongs());
		VibratePhone(pattern);
	}


	protected void displayTactonList() {
		startActivity(new Intent(this, TactonList.class));
	}

}
